package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.StatusConstant;
import com.sky.context.ThreadLocalUtil;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BusinessException;
import com.sky.mapper.DishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishFlavorService;
import com.sky.service.DishService;
import com.sky.service.SetmealDishService;
import com.sky.service.SetmealService;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private SetmealService setmealService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public Integer findByCategoryId(Long id) {
      Integer count = dishMapper.findByCategoryId(id);
        return count;
    }

    @Override
    public void save(DishDTO dto) {
        String name = dto.getName();
        BigDecimal price = dto.getPrice();
        String description = dto.getDescription();
        if(!name.matches("[0-9A-Za-z\\u4E00-\\u9FA5]{3,20}")){
            throw new BusinessException("套餐名称输入不符，请输入3-20个字符");
        }
        if(!price.toString().matches("^([1-9][0-9]*)+(\\.[0-9]{1,2})?$")){
            throw new BusinessException("套餐价格格式有误，请输入大于零且最多保留两位小数的金额");
        }
        if(!description.matches("[0-9A-Za-z\\u4E00-\\u9FA5]{0,200}")){
            throw new BusinessException("套餐描述输入不符，请输入少于200个字");
        }
        if (dto.getFlavors().size()>4) {
            throw new BusinessException("最多选择4中口味");
        }
        //业务校验

        Dish dish = dishMapper.findByName(name);
        if(dish!=null){
            throw  new BusinessException("菜名已存在");
        }
        //转换为dish
        dish=new Dish();
        BeanUtil.copyProperties(dto,dish);
        dish.setStatus(StatusConstant.DISABLE);
        //调用mapper新增,并返回主键
        dishMapper.save(dish);
        List<DishFlavor> flavors = dto.getFlavors();
        if(CollectionUtil.isNotEmpty(flavors)){
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dish.getId());
            }
            dishFlavorService.save(flavors);
        }
        Set keys = redisTemplate.keys("dish:*");
        redisTemplate.delete(keys);
        log.warn("缓存清除!");
    }

    @Override
    public PageResult findByPage(DishPageDTO dto) {
        Integer page = dto.getPage();
        Integer pageSize = dto.getPageSize();
        if(page==0){
            page=1;
        }
        if(pageSize==0){
            pageSize=10;
        }
        PageHelper.startPage(page,pageSize);
       List<DishVO> dishVO = dishMapper.findByList(dto);
        PageInfo<DishVO> pageInfo = PageInfo.of(dishVO);
        return new PageResult(pageInfo.getTotal(),dishVO);
    }

    @Override
    public DishVO findById(Long id) {
      Dish dish =  dishMapper.findById(id);

      List<DishFlavor> list = dishFlavorService.findByDishId(id);
        DishVO dishVO = BeanUtil.copyProperties(dish, DishVO.class);
        dishVO.setFlavors(list);
        return dishVO;
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        //校验
        if(CollectionUtil.isEmpty(ids)){
            throw new BusinessException("请选择要删除的菜品");
        }

        Integer count1 = setmealDishService.findByDishIds(ids);
        if(count1 >0){
            throw new BusinessException("有套餐关联的菜品无法删除");
        }
        Integer count2 =dishMapper.findByIds(ids);
        if(count2>0){
            throw new BusinessException("在售菜品无法删除");
        }
        //先删除口味表中的数据
        dishFlavorService.deleteByDishIds(ids);
        //再删除菜品
        dishMapper.deleteByIds(ids);
        Set keys = redisTemplate.keys("dish:*");
        redisTemplate.delete(keys);
        log.warn("缓存清除!");
    }

    @Override
    public void update(DishDTO dto) {

        String name = dto.getName();
        BigDecimal price = dto.getPrice();
        String description = dto.getDescription();
        if(!name.matches("[0-9A-Za-z\\u4E00-\\u9FA5]{3,20}")){
            throw new BusinessException("套餐名称输入不符，请输入3-20个字符");
        }
        if(!price.toString().matches("^(([1-9]{1}\\d*)|(0{1}))(\\.\\d{2})$")){
            throw new BusinessException("套餐价格格式有误，请输入大于零且最多保留两位小数的金额");
        }
        if(!description.matches("[0-9A-Za-z\\u4E00-\\u9FA5]{0,200}")){
            throw new BusinessException("套餐描述输入不符，请输入少于200个字");
        }
        if (dto.getFlavors().size()>4) {
            throw new BusinessException("最多选择4中口味");
        }
        //业务校验
        Dish dish = dishMapper.findByName(name);
        if(dish!=null && dish.getId()!= dto.getId()){
            throw  new BusinessException("菜名已存在");
        }
        dish=new Dish();
        BeanUtil.copyProperties(dto,dish);
        dishMapper.update(dish);
        List<DishFlavor> flavors = dto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dish.getId());
        }
        dishFlavorService.deleteByDishId(dish.getId());
        dishFlavorService.save(flavors);
        Set keys = redisTemplate.keys("dish:*");
        redisTemplate.delete(keys);
        log.warn("缓存清除!");

    }

    @Override
    public void updateStatus(Dish dish) {

        dishMapper.update(dish);

        if(dish.getStatus()==StatusConstant.DISABLE){
            setmealService.updateStatusByDish(dish.getId(),dish.getStatus());

        }
        Set keys = redisTemplate.keys("dish:*");
        redisTemplate.delete(keys);
        log.warn("缓存清除!");
    }

    @Override
    public List<DishVO> findList(DishPageDTO dto) {

       return dishMapper.findByList(dto);
    }

    /*@Override
    public void updateStatusBySetmealIds(List<Long> ids, Integer status) {
        Long updateUser= ThreadLocalUtil.getCurrentId();
        LocalDateTime updateTime=LocalDateTime.now();
        dishMapper.updateStatusBySetmealIds(ids,status,updateTime,updateUser);

    }*/

    @Override
    public Integer findBySetmealId(Long id) {
       Integer count = dishMapper.findBySetmealId(id);
       return count;
    }

    @Override
    public List<DishVO> findListByCategory4App(DishPageDTO dishPageDTO) {

        Long categoryId = dishPageDTO.getCategoryId();
        if (redisTemplate.hasKey("dish:"+categoryId)) {
            log.warn("缓存加载!");
            return (List<DishVO>) redisTemplate.opsForValue().get("dish:"+categoryId);
        }
        List<DishVO> list = dishMapper.findByList(dishPageDTO);
        if (CollectionUtil.isNotEmpty(list)) {
            for (DishVO dishVO : list) {
                Long dishVOId = dishVO.getId();
                List<DishFlavor> flavors = dishFlavorService.findByDishId(dishVOId);
                dishVO.setFlavors(flavors);
            }
        }
        redisTemplate.opsForValue().set("dish:"+categoryId,list);
        log.warn("菜品分类{}现已加入缓存套餐",categoryId);
        return list;
    }


}
